package com.maegul.data.dao;

import java.util.List;

import javax.persistence.EntityManager;

/**
 * Interface que modela el comportamiento del DAO base que utiliza esta
 * aplicacion, cualquier nueva implementacion debe implementar esta interface
 * para mantener la modificabilidad de la aplicacion correcta
 * 
 * @param <EntityClass>
 *            Entidad que modela la tabla usada por el DAO
 */
public interface DAO<EntityClass> {

	/**
	 * Busca todas las filas de la tabla modelada por la entidad del DAO
	 * implementado
	 * 
	 * @return Una coleccion con todas las entidades (filas) de la tabla
	 */
	List<EntityClass> findAll();

	/**
	 * Busca una entidad dado su identificador (numerico)
	 * 
	 * @param id
	 *            El identificador de la entidad (fila) a buscar
	 * @return La entidad que tiene como id el id especificado como parametro,
	 *         <code>null</code> en caso que no exista dicho id en la tabla
	 */
	EntityClass findById(int id);

	/**
	 * Busca una entidad dada una propiedad del Objeto que la modela
	 * 
	 * @param propertyName
	 *            Nombre de la propiedad de la entidad
	 * @param propertyValue
	 *            Valor de la propiedad
	 * @return La entidad que tiene la propiedad especificada, <code>null</code>
	 *         en caso que dicha propiedad no exista
	 */
	EntityClass findByProperty(String propertyName, Object propertyValue);

	/**
	 * Elimina una entidad de la base de datos.
	 * 
	 * @param entity
	 *            La entidad a eliminar
	 */
	void remove(EntityClass entity);

	/**
	 * Elimina una entidad seguramente, asegurandose que el ID de la entidad
	 * exista en la base de datos, y luego eliminandolo
	 * 
	 * @param entity
	 *            La entidad a eliminar
	 */
	void removeSafely(EntityClass entity);

	/**
	 * Persiste una entidad en la base de datos
	 * 
	 * @param entity
	 *            La entidad a persistir en la base de datos
	 */
	void persist(EntityClass entity);

	/**
	 * Persiste/actualiza una entidad en la base de datos pero el EntityManager
	 * no realiza el manejo de dicha entidad, por lo que debe ser buscada luego
	 * de usar este metodo
	 * 
	 * @param entity
	 *            La entidad nueva para ser persistida/actualizada
	 * @return La entidad nueva, es decir, la que se encuentra en la base de
	 *         datos
	 */
	EntityClass merge(EntityClass entity);

	/**
	 * Retorna el EntityManager que maneja las transacciones de este DAO
	 * 
	 * @return El EntityManager del DAO implementado
	 */
	EntityManager getEntityManager();

	/**
	 * Retorna el numero de entidades (filas) que tiene la tabla de este DAO
	 * 
	 * @return El numero de entidades que tiene la tabla
	 */
	long size();

	/**
	 * Retorna la entidad que modela la tabla de este DAO
	 * 
	 * @return La entidad que modela la tabla de este DAO
	 */
	Class<EntityClass> getClazz();

	/**
	 * Busca una entidad por su referencia basica ID, por lo que se asegura que
	 * la entidad existe
	 * 
	 * @param entity
	 *            La entidad que se desea buscar por referencia
	 * @return La entidad buscada
	 */
	EntityClass getReference(EntityClass entity);
}
